/**
 * file-selector.js - 文件选择器公共组件
 * 功能：通用的文件浏览和选择弹窗组件
 * 使用方式：
 *   1. 在 HTML 中引入此 JS 文件和对应的模态框 HTML
 *   2. 调用 FileSelector.show(config) 显示文件选择器
 *   3. 通过 config.onSelect 回调接收选中的文件
 */

/**
 * 文件选择器组件
 */
const FileSelector = {
    /**
     * 组件配置
     */
    config: {
        // 选择文件的回调函数
        onSelect: null,
        // 初始路径（用于定位到指定目录）
        initialPath: '',
        // 是否只允许选择文件（不允许选择文件夹）
        fileOnly: true,
        // 模态框标题
        title: '选择文件'
    },

    /**
     * 当前搜索关键词
     */
    currentSearchKeyword: '',

    /**
     * 当前浏览路径
     */
    currentPath: '',

    /**
     * DOM 元素引用
     */
    elements: {
        modal: null,
        modalTitle: null,
        breadcrumb: null,
        fileTableBody: null,
        statusMsg: null,
        searchInput: null,
        searchBtn: null
    },

    /**
     * 初始化 DOM 引用
     */
    initElements() {
        if (!this.elements.modal) {
            this.elements.modal = document.getElementById('fileSelectModal');
            this.elements.modalTitle = document.getElementById('fileSelectorTitle');
            this.elements.breadcrumb = document.getElementById('modalBreadcrumb');
            this.elements.fileTableBody = document.getElementById('modalFileTableBody');
            this.elements.statusMsg = document.getElementById('modalStatusMsg');
            this.elements.searchInput = document.getElementById('modalSearchInput');
            this.elements.searchBtn = document.getElementById('modalSearchBtn');

            // 绑定搜索框 Enter 键事件
            if (this.elements.searchInput) {
                this.elements.searchInput.addEventListener('keypress', (e) => {
                    if (e.key === 'Enter') {
                        this.handleSearch();
                    }
                });
            }
        }
    },

    /**
     * 显示文件选择器
     * @param {Object} config - 配置对象
     * @param {Function} config.onSelect - 选择文件的回调函数，参数为文件节点对象
     * @param {string} [config.initialPath=''] - 初始路径
     * @param {boolean} [config.fileOnly=true] - 是否只允许选择文件
     * @param {string} [config.title='选择文件'] - 模态框标题
     */
    show(config = {}) {
        // 合并配置
        this.config = {
            onSelect: config.onSelect || null,
            initialPath: config.initialPath || '',
            fileOnly: config.fileOnly !== undefined ? config.fileOnly : true,
            title: config.title || '选择文件'
        };

        // 初始化 DOM 引用
        this.initElements();

        // 清空搜索框和搜索关键词
        this.currentSearchKeyword = '';
        if (this.elements.searchInput) {
            this.elements.searchInput.value = '';
        }

        // 设置标题
        if (this.elements.modalTitle) {
            this.elements.modalTitle.textContent = this.config.title;
        }

        // 确定初始路径
        let startPath = '';
        if (this.config.initialPath) {
            // 如果提供了初始路径，提取目录路径（去掉最后一个/之后的文件名）
            const lastSlashIndex = this.config.initialPath.lastIndexOf('/');
            if (lastSlashIndex > 0) {
                // 有路径且不在根目录
                startPath = this.config.initialPath.substring(0, lastSlashIndex);
            } else if (lastSlashIndex === 0) {
                // 在根目录下的文件
                startPath = '';
            } else {
                // 没有/，说明是相对路径或只有文件名
                startPath = '';
            }
        }

        // 加载目录
        this.loadDirectory(startPath);

        // 显示模态框
        this.elements.modal.style.display = 'flex'; // 使用 flex 以配合 CSS 居中

        // 阻止背景滚动
        document.body.classList.add('modal-open');
    },

    /**
     * 隐藏文件选择器
     */
    hide() {
        if (this.elements.modal) {
            this.elements.modal.style.display = 'none';

            // 恢复背景滚动
            document.body.classList.remove('modal-open');
        }
    },

    /**
     * 处理搜索
     */
    handleSearch() {
        if (this.elements.searchInput) {
            this.currentSearchKeyword = this.elements.searchInput.value.trim();
            this.loadDirectory(this.currentPath, this.currentSearchKeyword);
        }
    },

    /**
     * 加载指定路径的目录内容
     * @param {string} fullPath - 完整路径
     * @param {string} nameFilter - 可选的搜索过滤条件
     */
    async loadDirectory(fullPath, nameFilter = '') {
        try {
            // 更新当前路径
            this.currentPath = fullPath;

            // 显示加载状态
            this.showLoading();

            // 如果不是搜索触发的加载，清空搜索框和搜索关键词
            if (arguments.length === 1) {
                this.currentSearchKeyword = '';
                if (this.elements.searchInput) {
                    this.elements.searchInput.value = '';
                }
            }

            // 调用 API 获取目录内容
            const response = await API.lazyLoadFile(fullPath, nameFilter);

            // 检查响应状态
            if (response.code === 200 && response.data) {
                // 渲染文件列表
                this.renderFileList(response.data);

                // 更新面包屑导航
                this.updateBreadcrumb(fullPath);

                // 隐藏状态消息
                this.hideStatus();
            } else {
                // 显示错误消息
                this.showError(response.message || '加载失败');
            }
        } catch (error) {
            console.error('加载目录失败:', error);
            this.showError('网络错误，请稍后重试');
        }
    },

    /**
     * 渲染文件列表到表格
     * @param {Array} fileList - 文件/文件夹节点数组
     */
    renderFileList(fileList) {
        const tbody = this.elements.fileTableBody;

        // 清空表格内容
        tbody.innerHTML = '';

        // 如果列表为空
        if (!fileList || fileList.length === 0) {
            tbody.innerHTML = `
                <tr>
                    <td colspan="4" style="text-align: center; color: #7f8c8d;">
                        当前目录为空
                    </td>
                </tr>
            `;
            return;
        }

        // 排序：文件夹在前，文件在后
        const sortedList = [...fileList].sort((a, b) => {
            if (a.directory === b.directory) {
                return a.name.localeCompare(b.name);
            }
            return a.directory ? -1 : 1;
        });

        // 渲染每个文件/文件夹节点
        sortedList.forEach(node => {
            const row = this.createFileRow(node);
            tbody.appendChild(row);
        });
    },

    /**
     * 创建单个文件/文件夹的表格行
     * @param {Object} node - 文件节点对象
     * @returns {HTMLTableRowElement} 表格行元素
     */
    createFileRow(node) {
        const row = document.createElement('tr');
        row.style.cursor = 'pointer';

        // 文件夹：点击进入目录
        if (node.directory) {
            row.classList.add('folder-row');
            row.addEventListener('click', () => {
                this.loadDirectory(node.fullPath);
            });
        } else {
            // 文件：根据 fileOnly 配置决定是否可选
            if (this.config.fileOnly) {
                row.addEventListener('click', () => {
                    this.selectFile(node);
                });
            }
        }

        // 鼠标悬停效果
        row.addEventListener('mouseenter', () => {
            row.style.backgroundColor = '#f0f8ff';
        });
        row.addEventListener('mouseleave', () => {
            row.style.backgroundColor = '';
        });

        // 类型列（图标）
        const typeCell = document.createElement('td');
        typeCell.style.textAlign = 'center';
        typeCell.style.fontSize = '1.5em';
        typeCell.textContent = node.directory ? '📁' : '📄';
        row.appendChild(typeCell);

        // 名称列
        const nameCell = document.createElement('td');
        nameCell.textContent = node.name;
        if (node.directory) {
            nameCell.style.fontWeight = '600';
            nameCell.style.color = '#3498db';
        }
        row.appendChild(nameCell);

        // 大小列
        const sizeCell = document.createElement('td');
        sizeCell.textContent = node.directory ? '-' : (node.formattedSize || this.formatFileSize(node.size));
        sizeCell.style.color = '#7f8c8d';
        row.appendChild(sizeCell);

        // 修改时间列
        const timeCell = document.createElement('td');
        timeCell.textContent = node.lastModified ? this.formatDate(node.lastModified) : '-';
        timeCell.style.color = '#7f8c8d';
        timeCell.style.fontSize = '0.9em';
        row.appendChild(timeCell);

        return row;
    },

    /**
     * 选择文件（触发回调）
     * @param {Object} node - 文件节点对象
     */
    selectFile(node) {
        // 调用配置的回调函数
        if (typeof this.config.onSelect === 'function') {
            this.config.onSelect(node);
        }

        // 关闭弹窗
        this.hide();
    },

    /**
     * 更新面包屑导航
     * @param {string} fullPath - 当前完整路径
     */
    updateBreadcrumb(fullPath) {
        const breadcrumb = this.elements.breadcrumb;

        // 清空面包屑
        breadcrumb.innerHTML = '';

        // 根目录项（始终可点击）
        const isAtRoot = !fullPath || fullPath === '';
        const rootItem = this.createBreadcrumbItem('根目录', '', isAtRoot);
        breadcrumb.appendChild(rootItem);

        // 如果不是根目录，解析路径并创建面包屑项
        if (fullPath) {
            const pathParts = fullPath.split('/').filter(part => part.length > 0);
            let cumulativePath = '';

            pathParts.forEach((part, index) => {
                // 构建累积路径
                cumulativePath += (cumulativePath ? '/' : '') + part;

                // 添加分隔符
                const separator = document.createElement('span');
                separator.className = 'breadcrumb-separator';
                separator.textContent = ' / ';
                breadcrumb.appendChild(separator);

                // 创建面包屑项
                const isLast = (index === pathParts.length - 1);
                const item = this.createBreadcrumbItem(part, cumulativePath, isLast);
                breadcrumb.appendChild(item);
            });
        }
    },

    /**
     * 创建面包屑导航项
     * @param {string} text - 显示文本
     * @param {string} path - 对应路径
     * @param {boolean} isActive - 是否为当前激活项
     * @returns {HTMLSpanElement} 面包屑项元素
     */
    createBreadcrumbItem(text, path, isActive) {
        const item = document.createElement('span');
        item.className = 'breadcrumb-item' + (isActive ? ' active' : '');
        item.textContent = text;
        item.dataset.path = path;

        // 非激活项可点击
        if (!isActive) {
            item.style.cursor = 'pointer';
            item.addEventListener('click', () => {
                this.loadDirectory(path);
            });
        }

        return item;
    },

    /**
     * 格式化文件大小
     * @param {number} bytes - 字节数
     * @returns {string} 格式化后的大小字符串
     */
    formatFileSize(bytes) {
        if (bytes === 0) return '0 B';
        if (!bytes) return '-';

        const units = ['B', 'KB', 'MB', 'GB', 'TB'];
        const k = 1024;
        const i = Math.floor(Math.log(bytes) / Math.log(k));

        return (bytes / Math.pow(k, i)).toFixed(2) + ' ' + units[i];
    },

    /**
     * 格式化日期时间
     * @param {string} dateStr - 日期字符串
     * @returns {string} 格式化后的日期字符串
     */
    formatDate(dateStr) {
        if (!dateStr) return '-';

        try {
            const date = new Date(dateStr);
            const year = date.getFullYear();
            const month = String(date.getMonth() + 1).padStart(2, '0');
            const day = String(date.getDate()).padStart(2, '0');
            const hours = String(date.getHours()).padStart(2, '0');
            const minutes = String(date.getMinutes()).padStart(2, '0');

            return `${year}-${month}-${day} ${hours}:${minutes}`;
        } catch (e) {
            return dateStr;
        }
    },

    /**
     * 显示加载状态
     */
    showLoading() {
        this.elements.fileTableBody.innerHTML = `
            <tr>
                <td colspan="4" style="text-align: center; color: #7f8c8d;">
                    <span class="loading">正在加载...</span>
                </td>
            </tr>
        `;
    },

    /**
     * 显示错误消息
     * @param {string} message - 错误消息文本
     */
    showError(message) {
        const statusMsg = this.elements.statusMsg;
        statusMsg.textContent = message;
        statusMsg.className = 'status error';
        statusMsg.style.display = 'block';

        // 清空文件列表
        this.elements.fileTableBody.innerHTML = `
            <tr>
                <td colspan="4" style="text-align: center; color: #e74c3c;">
                    加载失败，请重试
                </td>
            </tr>
        `;
    },

    /**
     * 隐藏状态消息
     */
    hideStatus() {
        this.elements.statusMsg.style.display = 'none';
    }
};

// ==================== 全局辅助函数 ====================
/**
 * 关闭文件选择器模态框（供 HTML 调用）
 */
function closeFileSelectModal() {
    FileSelector.hide();
}

// 点击模态框外部区域关闭弹窗
window.addEventListener('click', function (event) {
    const modal = document.getElementById('fileSelectModal');
    if (event.target === modal) {
        closeFileSelectModal();
    }
});